﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using DBUtils;

/// <summary>
/// 该页面对应着功能说明书的申请加班页。
/// </summary>
public partial class SubmitOverTime_DefaultSubmit : System.Web.UI.Page
{
    //左边日历中的节假日
    ArrayList alHolidayL = new ArrayList();
    //右边日历中的节假日
    ArrayList alHolidayR = new ArrayList();
    //存放员工信息
    Employee emp;
    Employee ceo;
    /// <summary>
    /// 网页初始化时执行该方法。
    /// 设置控件属性，获取员工编号信息和员工其他信息，并调用 ReCalculateHoliday 方法. 
    /// 该过程调用 Employee.GetEmployeeInfo(iEmpID, emp) 函数，从数据库中获取员工的其他信息。
    /// 该过程调用 Employee.GetCEOInfo(iCEOID) 函数，从数据库中获取总经理的员工编号。
    /// 该过程调用 Employee.GetEmployeeInfo(iCEOID, empCEO) 函数，从数据库中获取总经理的其他信息。
    /// 该过程调用 ReCalculateHoliday() 函数，计算日历控件当月所包含的国定假日。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        //获取员工信息
        emp = new Employee();
        Employee.GetEmployeeInfo(Convert.ToInt32(Session["EmployeeID"]), emp);
        lblName.Text = emp.Name;

        //获取总经理的信息
        ceo = new Employee();
        int ceoid = 0;
        int ok = Employee.GetCEOInfo(ref ceoid);
        Employee.GetEmployeeInfo(ceoid, ceo);
        if (!IsPostBack)
        {
            //添加部门经理
            cmbApproverList.Items.Add(emp.ManagerName);
            cmbApproverList.Items.Add(ceo.Name);
        }
    }

    /// <summary>
    /// 该方法计算指定月份所包含的国定假日。该过程调用 
    /// SubmitLvReq.GetHoliday(cldStartDate.SelectedDate, alHolidayL) 和 
    /// SubmitLvReq.GetHoliday(cldEndDate.SelectedDate, alHolidayR) 函数，
    /// 在数据库中检索该月的国定假日。
    /// </summary>
    public void ReCalculateHoliday()
    {
        if (SubmitLvReq.GetHoliday(cldStartDate.SelectedDate, alHolidayL) == 0)
        {
            lblErrorMsg.Text = "开始时间没有选定";
        }
        if (SubmitLvReq.GetHoliday(cldEndDate.SelectedDate, alHolidayR) == 0)
        {
            lblErrorMsg.Text = "结束时间没有选定";
        }
    }

    /// <summary>
    /// 该函数根据用户选定的加班日期，返回加班的总小时数，如果加班时间不正确，则返回 0。
    /// 该过程调用 ReCalculateHoliday() 函数，计算日历控件当月所包含的国定假日。
    /// </summary>
    /// <returns>加班的总小时数</returns>
    public int CalculateHours()
    {
        int hour1 = Convert.ToInt32(cmbStartTime.SelectedValue);

        int hour2 = Convert.ToInt32(cmbEndTime.SelectedValue);

        DateTime begin = cldStartDate.SelectedDate.Date.AddHours(hour1);
        DateTime end = cldEndDate.SelectedDate.Date.AddHours(hour2);
        DateTime time1 = DateTime.Now;
        int time = 0;
        if (begin.CompareTo(end) < 0)
        {
            if (begin.Day == end.Day)
            {
                if (this.IsHoliday(begin) || this.IsWeekend(begin))
                {
                    time = 0;
                }
                else
                {
                    time = (int)end.Hour - (int)begin.Hour;
                }
            }
            else
            {
                DateTime daytime = end.Date.AddDays(-1);
                if (this.IsHoliday(begin) || this.IsWeekend(begin))
                {
                    time = 0;
                }
                else
                {
                    time += 18 - (int)begin.Hour;
                }

                int i = 1;
                for (time1 = begin.AddDays(1).Date; time1.CompareTo(daytime) <= 0; time1 = time1.AddDays(1))
                {
                    if (!(this.IsHoliday(time1) || this.IsWeekend(time1)))
                    {
                        time += 8;
                        i++;
                    }
                }
                if (!this.IsHoliday(end) && !this.IsWeekend(end))
                {
                    time += (int)end.Hour;
                }
            }
            lblTotalHours.Text = "一共请假小时数为：" + time.ToString();
        }
        else
        {
            return 0;
        }
        return time;

    }

    /// <summary>
    /// 该函数计算某指定日期是否为国定假日
    /// </summary>
    /// <param name="dt">指定的日期</param>
    /// <returns>若返回为True，则指定的日期是国定假日</returns>
    public bool IsHoliday(DateTime dt)
    {
        ArrayList today = new ArrayList();
        //获取dt所在月份的所有假日
        SubmitLvReq.GetHoliday(dt, today);
        //遍历该月假日
        foreach (object item in today)
        {
            if (Convert.ToDateTime(item).Day == dt.Day)//如果这一天是假日则返回真
                return true;
        }
        return false;//这天不是假日返回假
    }

    /// <summary>
    /// 该函数计算某指定日期是否为国定假日
    /// </summary>
    /// <param name="dt">指定的日期</param>
    /// <returns>若返回为True，则指定的日期是国定假日</returns>
    public bool IsWeekend(DateTime dt)
    {

        if ((dt.DayOfWeek == DayOfWeek.Saturday) || (dt.DayOfWeek == DayOfWeek.Sunday))
            return true;//这天是周末
        else
            return false;
    }

    /// <summary>
    /// 该方法将按加班日期填充加班小时下拉框，如果是工作日，则可选时间是下午18点到次日的9点；
    /// 如果是双休日或假日，则可选时间是上午9点到下午18点。
    /// </summary>
    /// <param name="cmbList">要填充的下拉框</param>
    /// <param name="dt">加班所在的日期，以此来判定是否为工作日</param>
    /// <param name="iOffset">偏移量，一般取 0 或 1，为 1 即表示结束时间要比开始时间晚一个小时</param>
    public void FillHourList(DropDownList cmbList, DateTime dt, int iOffset)
    {
         
    }

    /// <summary>
    /// 该方法当网页生成“开始时间”日历控件的每一个单元格时自动调用。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldStartDate_DayRender(object sender, DayRenderEventArgs e)
    {

    }

    /// <summary>
    /// 该方法当网页生成“结束时间”日历控件的每一个单元格时自动调用.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldEndDate_DayRender(object sender, DayRenderEventArgs e)
    {

    }

    /// <summary>
    /// 当用户改变“结束时间”日历控件的当前月份时，
    /// 该方法将重新设定日历控件的选中日期，并重新计算当前月份的国定假日。
    /// 该过程调用 ReCalculateHoliday() 函数，计算日历控件当月所包含的国定假日。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldEndDate_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
    {
        ReCalculateHoliday();
    }

    /// <summary>
    /// 当用户改变“开始时间”日历控件的当前月份时，
    /// 该方法将重新设定日历控件的选中日期，并重新计算当前月份的国定假日。
    /// 该过程调用 ReCalculateHoliday() 函数，计算日历控件当月所包含的国定假日。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldStartDate_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
    {
        ReCalculateHoliday();
    }

    /// <summary>
    /// 当用户单击“计算时间”按钮时，该方法计算并显示用户加班的总小时数。
    /// 该过程调用 CalculateHours() 函数，计算用户加班的总小时数。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnCalculate_Click(object sender, EventArgs e)
    {
        if (this.cldStartDate.SelectedDate.CompareTo(this.cldEndDate.SelectedDate) > 0)
        {
            this.Response.Write("<script>alert('" + "加班时间设置错误" + "');</script>");
        }

        int hours = CalculateHours();
        lblTotalHours.Text = "一共加班小时数为：" + hours.ToString();
        lblTotalHours.Visible = true;

    }

    /// <summary>
    /// 当用户对“开始时间”日历控件进行操作时，该方法重新计算国定假日。
    /// 该过程调用 ReCalculateHoliday()  函数，重新计算国定假日。
    /// 该过程还调用 FillHourList(cmbStartTime, cldStartDate.SelectedDate, 0) 函数，
    /// 填充下拉框。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldStartDate_SelectionChanged(object sender, EventArgs e)
    {
        ReCalculateHoliday();
    }

    /// <summary>
    /// 当用户对“结束时间”日历控件进行操作时，该方法重新计算国定假日。
    /// 该过程调用 ReCalculateHoliday()  函数，重新计算国定假日。
    /// 该过程还调用 FillHourList(cmbStartTime, cldStartDate.SelectedDate, 0) 函数，
    /// 填充下拉框。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void cldEndDate_SelectionChanged(object sender, EventArgs e)
    {
        ReCalculateHoliday();
    }

    /// <summary>
    /// 当用户单击“提交”按钮时，该方法将加班请求保存到数据库中。
    /// 该过程调用 CalculateHours() 函数，计算用户加班的总小时数。
    /// 该过程调用 SubmitOTReq.AddOTReq(CInt(Session("EmployeeID")), iType, DateTime.Now, dtStart, dtEnd, iApproverID, iTotalHours, txtReason.Text.Trim()) 函数，
    /// 向数据库提交该加班请求。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (txtReason.Text.Trim().Length == 0)
        {
            lblErrorMsg.Text = "加班原因不能为空！";
            return;
        }

        //设置加班时间
        DateTime dtStart = cldStartDate.SelectedDate.AddHours(Convert.ToDouble(cmbStartTime.SelectedValue));
        DateTime dtEnd = cldEndDate.SelectedDate.AddHours(9 - Convert.ToDouble(cmbEndTime.SelectedValue));

        int ihours = CalculateHours();//计算加班天数
        int inomal = 0;//存放常规加班天数
        int iApproverID = 0;

        int ok = SubmitLvReq.GetNormalLeaveDays(ref inomal);
        if (ihours > inomal * 5)//如果加班天数大于常规
        {
            this.cmbApproverList.SelectedIndex = 1;
            Response.Write(cmbApproverList.SelectedValue.ToString());
        }

        if (cmbApproverList.SelectedIndex == 1)//如果审批人是CEO
        {
            iApproverID = ceo.EmployeeID;
        }
        else
        {
            iApproverID = emp.ManagerID;
        }

        //提交加班信息
        ok = SubmitLvReq.AddLeaveReq(Convert.ToInt32(Session["EmployeeID"]), DateTime.Now, dtStart, dtEnd, iApproverID, ihours, txtReason.Text.Trim());
        if (ok == 1)
        {
            this.Response.Write("<script>alert('" + "成功提交加班信息" + "');</script>");//弹出成功信息
        }
    }
}
